import React, { PureComponent } from 'react'
import { Upload, Icon, Modal, message, Button } from 'antd'
import { reqImgDelete } from '../../api'
import PropTypes from 'prop-types'
import { getApp } from '../../utils'

function getBase64(file) {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = () => resolve(reader.result)
    reader.onerror = (error) => reject(error)
  })
}

class PicturesWall extends PureComponent {
  constructor(props) {
    super(props)

    // 如果传入了imgs属性
    const { max } = this.props

    /**
     * 默认最多能传8张图片
     * @type {PicturesWall.props.count | number}
     */
    this.max = max || 8
    /**
     * 如果对图片做了操作，就是true
     */
    this.hasOptions = false

    // 这里的 fileList 的结构为：
    // [
    // 	{
    // 		uid: '-1',
    // 		name: 'xxx.png',
    // 		status: 'done',
    // 		url: 'http://www.baidu.com/xxx.png',
    // 	},
    // ],
    this.state = {
      previewVisible: false, // 是否显示大图预览界面
      previewImage: '', // 大图的url
      fileList: [], // 这个是预览的时候要读取的数据，这个写法是官网固定的。
      fileListSubmit: [], // 这个是提交的时候要读取的数据，里面存储的是云存储的地址组成的数组。
    }
  }

  /**
   * 获取所有已经上传图片文件名的数组
   */
  getImgs = () => (this.hasOptions ? this.state.fileListSubmit : false)

  handleCancel = () => this.setState({ previewVisible: false })

  beforeUpload = (file) => {
    const app = getApp()
    const reader = new FileReader()

    reader.readAsDataURL(file)
    reader.onloadend = () => {
      const cloudPath = `${
        process.env.REACT_APP_PICTURE_UPLOAD_URL
      }/${new Date().valueOf()}_${file.name}`

      app
        .uploadFile({
          cloudPath,
          filePath: file,
        })
        .then(async (res) => {
          this.hasOptions = true
          this.state.fileListSubmit.push(res.fileID)
        })
        .catch((err) => {
          console.log(err)
        })
    }

    return false
  }

  handlePreview = async (file) => {
    if (!file.url && !file.preview) {
      file.preview = await getBase64(file.originFileObj)
    }

    this.setState({
      previewImage: file.url || file.preview,
      previewVisible: true,
    })
  }

  /**
   * 上传中、完成、失败都会调用这个函数。
   * @param file 当前操作的文件对象
   * @param fileList 当前的文件列表
   * @param event 上传中的服务端响应内容，包含了上传进度等信息，高级浏览器支持
   */
  handleChange = async ({ file, fileList, event }) => {
    const { status } = file

    // 这里有很多的很奇怪的bug
    // 视频中能够修改 file.name 但是我这里是无法修改的。
    switch (status) {
      case 'done':
        // 不再运行这里
        // console.log('测试，done 还运行吗？')
        const { response } = file
        if (response.status * 1 !== 0) {
          message.error('上传图片失败')
          break
        }
        // 一旦上传成功，将当前上传的file信息修正。实际上这个修改没用。
        message.success('图片已缓存，请点击提交上传。')
        const { name, url } = response.data

        // 尝试修改 this.state.fileListfile.name
        fileList.forEach((item) => {
          if (item.uid === file.uid) {
            item.name = name
            item.url = url
          }
        })

        break
      case 'removed':
        const fileName = file.response ? file.response.data.name : file.name

        // 默认删除集合 products 中的数据
        if (undefined === this.props.collectionName) {
          const { result } = await reqImgDelete(this.props.id, fileName)

          if (result.status * 1 === 200 && result.data.status * 1 === 0) {
            message.success('删除图片成功')
            break
          }
        } else if ('images_titles' === this.props.collectionName) {
          // console.log('测试删除图片 fileList', fileList)
          break
        }
        message.error('删除图片失败')
        break
      default:
        break
    }

    this.hasOptions = true
    this.setState({ fileList: [...fileList] })
  }

  /**
   * 这里有一个bug。
   * 如果已经上传了封面图，然后点击“所选分类”，loaddata之后会重新设置state。
   * 那么就会清除这个封面图片。
   * @param tempImgs 这是传入的imgs列表
   * */
  getFileList(tempImgs = null) {
    const { fileList } = this.state
    if (fileList.length > 0) return fileList

    const imgs = null !== tempImgs ? tempImgs : this.props.imgs

    let fileListFromImgs = []
    // 这是旧的方法，图片在本地
    if (imgs && imgs.length > 0)
      fileListFromImgs = imgs.map((img, index) => ({
        uid: -index,
        name: img,
        status: 'done',
        url: img,
      }))
    return fileListFromImgs
  }

  /**
   * 获取已经上传的图片的临时下载地址
   */
  getImgsTempUrl() {
    const app = getApp()
    let fileListFromImgs = []

    app
      .getTempFileURL({
        fileList: this.props.imgs,
      })
      .then((res) => {
        const { fileList } = res

        if (fileList.length > 0) {
          fileListFromImgs = fileList.map((el, index) => {
            const { tempFileURL, fileID } = el

            if (el.code === 'SUCCESS') {
              return {
                uid: -index,
                name: tempFileURL.split('/').pop(),
                status: 'done',
                url: tempFileURL,
              }
            } else {
              //获取下载链接失败
              // console.log('获取下载链接失败')
              return {
                uid: -index,
                name: fileID,
                status: 'done',
                url: fileID,
              }
            }
          })

          this.setState({ fileList: fileListFromImgs })
        }
      })
  }

  UNSAFE_componentWillMount() {
    // 初始化这里的fileList
    // const fileList = this.getFileList()
    // this.setState({ fileList })
  }

  /**
   * todo 这个生命周期要好好理解
   */
  componentWillReceiveProps(nextProps, nextContext) {
    // const fileList = this.getFileList(nextProps.imgs)
    // this.setState({ fileList })
  }

  componentDidMount() {
    this.getImgsTempUrl()
  }

  render() {
    const { previewVisible, previewImage, fileList } = this.state

    const uploadButton = (
      <div>
        <Button>
          <Icon type="upload" /> 上传图片
        </Button>
      </div>
    )
    return (
      <div>
        <Upload
          accept="image/*"
          name="image"
          listType="picture"
          fileList={fileList}
          beforeUpload={this.beforeUpload}
          onPreview={this.handlePreview}
          onChange={this.handleChange}
        >
          {fileList.length >= this.max ? null : uploadButton}
        </Upload>
        <Modal
          visible={previewVisible}
          footer={null}
          onCancel={this.handleCancel}
          className="picture-wall-wrapper"
        >
          <img
            alt="example"
            className="picture-wall-wrapper"
            src={previewImage}
          />
        </Modal>
      </div>
    )
  }
}

PicturesWall.propTypes = {
  id: PropTypes.string,
  imgs: PropTypes.array,
  max: PropTypes.number,
  collectionName: PropTypes.string,
}

export default PicturesWall
